package com.jacob.androidframe.base;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.text.TextUtils;

/**
 * 本类是PagerAdapter类的子类，专门用于在ViewPager中显示Fragment。
 * 本类适用于Fragment的数量较多的情况。
 * 本类会将不可见的Fragment直接删除，所以占用内存较少。但是由于Fragment会频繁的创建，所以效率上会稍差一些。
 * 
 * 注1：因为本类内部创建Fragment时，没有使用Tag或Id，所以无法像AdapterPagerFragmentBase那样动态移动或刷新Fragment。
 * 注2：本类的getItemPosition()方法固定返回POSITION_NONE，所以调用本类的notifyDataSetChanged()方法后，所有的Page都会被销毁并重建。
 * 
 * 如果Fragment数量较少，或需要动态移动或刷新Fragment，请考虑使用AdapterPagerFragmentBase类。
 * 
 */
public class AdapterPagerFragmentStateBase extends FragmentStatePagerAdapter
{
	private Context				mContext;
	private List<AbstractItem>	mItemList;
	
	public AdapterPagerFragmentStateBase(Context pContext, FragmentManager pFragmentManager)
	{
		this(pContext, pFragmentManager, null);
	}

	public AdapterPagerFragmentStateBase(Context pContext, FragmentManager pFragmentManager, List<AbstractItem> pItemList)
	{
		super(pFragmentManager);
		mContext = pContext;
		setItemList(pItemList);
	}
	
	@Override
	public int getCount()
	{
		return mItemList.size();
	}

	/**
	 * 当调用notifyDataSetChanged()方法时，ViewPager会调用本方法来决定每个Page是否要改变位置。
	 * 本方法覆盖了父类的实现，无论参数为什么，都返回POSITION_NONE。
	 */
	@Override
	public int getItemPosition(Object pObject)
	{
		return POSITION_NONE;
	}

	@Override
	public CharSequence getPageTitle(int pPosition)
	{
		CharSequence _PageTitle = mItemList.get(pPosition).getPageTitle();
		if (!TextUtils.isEmpty(_PageTitle)) {
			return _PageTitle;
		} else {
			return "";
		}
	}

	@Override
	public Fragment getItem(int pPosition)
	{
		Class<? extends Fragment> _FragmentClass = mItemList.get(pPosition).getFragmentClass();
		Bundle _BundleArgs = mItemList.get(pPosition).getBundleArgs();

		return Fragment.instantiate(getContext(), _FragmentClass.getName(), _BundleArgs);
	}
	
	@Override
	public void notifyDataSetChanged()
	{
		if (!checkList()) {
			throw new IllegalArgumentException("Unable to instantiate fragment. Please read " + getClass() + "'s Java doc. ");
		}
		super.notifyDataSetChanged();
	}

	public void setItemList(List<AbstractItem> pItemList)
	{
		if (pItemList == null) {
			mItemList = new ArrayList<AbstractItem>();
		} else {
			mItemList = new ArrayList<AbstractItem>(pItemList);
		}
		notifyDataSetChanged();
	}

	public void addItem(AbstractItem pItem)
	{
		if (pItem != null) {
			mItemList.add(pItem);
		}
		notifyDataSetChanged();
	}

	public void addItem(int pPosition, AbstractItem pItem)
	{
		if (pItem != null) {
			mItemList.add(pPosition, pItem);
		}
		notifyDataSetChanged();
	}

	public void addItemList(List<AbstractItem> pItemList)
	{
		if (pItemList != null) {
			mItemList.addAll(pItemList);
		}
		notifyDataSetChanged();
	}

	public void addItemList(int pPosition, List<AbstractItem> pItemList)
	{
		if (pItemList != null) {
			mItemList.addAll(pPosition, pItemList);
		}
		notifyDataSetChanged();
	}

	public void removeItem(int pPosition)
	{
		mItemList.remove(pPosition);
		notifyDataSetChanged();
	}
	
	protected Context getContext()
	{
		return mContext;
	}
	
	private boolean checkList()
	{
		// 检查ItemList是否为null
		if (mItemList == null) {
			return false;
		}
		// 检查ItemList中的数据
		for (AbstractItem _Item : mItemList) {
			// 检查Item是否为null
			if (_Item == null) {
				return false;
			}
			// 检查Item中的数据是否为null
			if ( _Item.getFragmentClass() == null) {
				return false;
			}
		}
		
		return true;
	}

	public static class AbstractItem
	{
		private CharSequence	mPageTitle;
		private Class<? extends Fragment>	mFragmentClass;
		private Bundle										mBundleArgs;

		public AbstractItem(CharSequence	pPageTitle, Class<? extends Fragment> pFragmentClass, Bundle pBundleArgs)
		{
			setPageTitle(pPageTitle);
			setFragmentClass(pFragmentClass);
			setBundleArgs(pBundleArgs);
		}
		
		public CharSequence getPageTitle() {
			return mPageTitle;
		}

		public void setPageTitle(CharSequence pPageTitle) {
			mPageTitle = pPageTitle;
		}

		public Class<? extends Fragment> getFragmentClass()
		{
			return mFragmentClass;
		}

		public void setFragmentClass(Class<? extends Fragment> pFragmentClass)
		{
			mFragmentClass = pFragmentClass;
		}

		public Bundle getBundleArgs()
		{
			return mBundleArgs;
		}

		public void setBundleArgs(Bundle pBundleArgs)
		{
			mBundleArgs = pBundleArgs;
		}
	}
}
